package resml

import (
	"io"
	"sync"
	"time"
)

// 资源存储接口
type Storage interface {
	Get(path string) (io.ReadCloser, Meta, error)         // 获取资源
	Meta(path string) (Meta, error)                       // 获取资源元数据
	List(path string) (*StorageInfo, error)               // 获取资源列表
	State(path string) (*StorageState, error)             // 对象的状态，如果状态不存在，则返回 nil
	Save(path string, meta Meta, content io.Reader) error // 保存资源
	Remove(path string) error                             // 删除资源
	Rename(oldpath, newpath string) error                 // 重命名资源
}

// 存储信息
type StorageInfo struct {
	Name        string         `json:"name,omitempty"`        // 目录/文件名；存储 Key
	Mime        string         `json:"mime,omitempty"`        // MIME 类型
	Size        int64          `json:"size,omitempty"`        // 大小
	AddTime     time.Time      `json:"addTime,omitempty"`     // 创建时间
	ModTime     time.Time      `json:"modTime,omitempty"`     // 修改时间
	IsContainer bool           `json:"isContainer,omitempty"` // 是否为容器：如目录
	Items       []*StorageInfo `json:"items,omitempty"`       // 子项
}

// 存储状态
type StorageState struct {
	writing     bool
	lastWriteAt time.Time
}

// 是否正在写入
func (s *StorageState) IsWriting() bool {
	return s.writing
}

// 最后写入时间
func (s *StorageState) LastWriteAt() time.Time {
	return s.lastWriteAt
}

// 存储状态池
type StorageStates struct {
	mu     sync.Mutex
	states map[string]*StorageState
}

// 是否正在写入
func (s *StorageStates) IsWriting(key string) bool {
	s.mu.Lock()
	defer s.mu.Unlock()
	if ss, found := s.states[key]; found {
		return ss.IsWriting()
	}
	return false
}

// 最后写入时间，如果 key 对象不是正在写入（未写或已写完），返回零值（time.IsZero() 为 true）
func (s *StorageStates) LastWriteAt(key string) time.Time {
	s.mu.Lock()
	defer s.mu.Unlock()
	if ss, found := s.states[key]; found {
		return ss.LastWriteAt()
	}
	var zero time.Time
	return zero
}

// 写入开始
func (s *StorageStates) WriteStarted(key string) *StorageState {
	s.mu.Lock()
	defer s.mu.Unlock()
	ss, found := s.states[key]
	if !found {
		ss = &StorageState{writing: true, lastWriteAt: time.Now()}
		s.states[key] = ss
	}
	return ss
}

// 写入完成
func (s *StorageStates) Writed(key string) {
	s.mu.Lock()
	defer s.mu.Unlock()
	delete(s.states, key)
}

// 获取对象状态
func (s *StorageStates) State(key string) *StorageState {
	return s.states[key]
}

// 创建存储状态池
func NewStorageStates() *StorageStates {
	return &StorageStates{states: make(map[string]*StorageState)}
}
